<?php

namespace appApi\components;


use yii\helpers\Json;
use yii\web\Response;

/**
 * 返回结果
 * @package appApi\components
 */
class ResultResponse extends Response
{
    public $status = ResultStatus::SUCCESS;
    public $errmsg = '';
    public $timestamp;
    public $attach = '';
    public $sign = '';
    public $result = '';
    public $format = RequestFormat::JSON;
    public $charset = 'UTF-8';
    public $callback = 'response';
    public $xmlRootName = 'xml';

    /**
     * 数组转换为xml对象
     * @param string|array $body
     * @param \SimpleXMLElement $xmlRoot
     */
    private function arrayToXml($body, \SimpleXMLElement &$xmlRoot)
    {
        foreach($body as $k => $v)
        {
            $key = is_numeric($k) ? "item$k" : $k;
            if(is_array($v))
            {
                $sub = $xmlRoot->addChild("$key");
                $this->arrayToXml($v, $sub);
            }
            else
            {
                $xmlRoot->addChild("$key", "$v");
            }
        }
    }

    /**
     * 转换数据为xml字符串
     * @param array|string $data
     * @param string $root
     * @return string|bool
     */
    public function toXml($data, $root='xml')
    {
        $xmlRoot = new \SimpleXMLElement("<?xml version=\"1.0\" encoding=\"$this->charset\" ?><$root></$root>");
        $this->arrayToXml($data, $xmlRoot);
        $str = $xmlRoot->asXML();
        return $str === false ? '' : $str;
    }

    /**
     * 转换数据为json字符串
     * @param array|string $data
     * @return string
     */
    public function toJson($data)
    {
        $json = Json::encode($data);
        return $json;
    }

    /**
     * 错误结果
     * @param string $format
     * @param int $status
     * @param string $errmsg
     * @param string $attach
     * @return ResultResponse
     */
    public function sendError($format=null, $status=null, $errmsg=null, $attach=null)
    {
        return $this->sendResult($format, $status, '', null, $errmsg, $attach);
    }

    /**
     * 发送结果
     * @param string $format
     * @param int $status
     * @param string $result
     * @param string $sign
     * @param string $errmsg
     * @param string $attach
     * @param int $timestamp
     * @return ResultResponse
     */
    public function sendResult($format=null, $status=null, $result=null, $sign=null, $errmsg=null, $attach=null, $timestamp=null) {
        $this->format = empty($format) ? $this->format : $format;
        $this->status = $status === null ? $this->status : $status;
        $this->result = $result === null ? $this->$result : $result;
        $this->sign = $sign === null ? $this->sign : $sign;
        $this->errmsg = $errmsg === null ? $this->errmsg : $errmsg;
        $this->attach = $attach === null ? $this->attach : $attach;
        $this->timestamp = $timestamp === null ? time() : $timestamp;
        $data = [
            'status' => $this->status,
            'result' => $this->result,
            'errmsg' => $this->errmsg,
            'timestamp' => $this->timestamp,
            'attach' => $this->attach,
            'sign' => $this->sign,
        ];
        $content = '';
        switch($this->format) {
            case RequestFormat::JSON:
                $content = $this->toJson($data);
                break;
            case RequestFormat::XML:
                $content = $this->toXml($data);
                break;
            case RequestFormat::JSONP:
                $content = $this->toJson($data);
                break;
        }
        $this->content = $content;
        $this->format = strtolower($this->format);
        return $this;
    }
}